import json
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.views.decorators.http import require_GET, require_POST, require_http_methods
import time
from django.db.models import Q
from users.models import *
from django.contrib.auth.hashers import make_password, check_password
from users.tools.net_tools import session_check, generate_session
from users.tools import aes
from users.tools import net_tools
from users.tools.net_tools import parse_request
from django.db.models import Q


# Create your views here.


# 登录
@require_http_methods(['POST', 'GET'])
def login(request):
    if request.method == 'GET':
        rsp = render(request, 'users/login.html')
        rsp.delete_cookie('who')
        rsp.delete_cookie('auth')
        return rsp
    elif request.method == 'POST':
        ask = json.loads(str(request.body, encoding='UTF-8'))
        rst = net_tools.get_json_temp()
        try:
            query = Users.objects.get(account=ask['account'], status=0)
            if not check_password(ask['password'], query.password):
                raise Exception('error password exception')
        except Exception as e:
            print(e)
            rst.meta['code'] = 500
            rst.meta['msg'] = '用户不存在、失效或密码错误'
            return JsonResponse(rst.__str__())
        else:  # 检查通过后，生成相应参数需要保存在cookie中
            auth = generate_session(request)
            account = ask['account']
            rst.data['auth'] = auth
            rst.data['account'] = account
            rsp = JsonResponse(rst.__str__())

            request.session[account] = auth
            request.session.set_expiry(60 * 60 * 2)

            query.last_ip = net_tools.get_ip(request)
            query.last_time = time.strftime(
                "%Y-%m-%d %H:%M:%S", time.localtime())
            query.session_id = request.session.session_key
            query.save()
            return rsp


# 检查注册用户信息是否已经存在
def check_unique(request):
    if request.method == 'GET':
        account = request.GET.get('account', None)
        belongs = request.GET.get('belongs', None)
        result = {
            'code': '200'
        }

        if Users.objects.filter(account=account).exists():
            result['code'] = 501
        if Users.objects.filter(belongs=belongs).exists():
            result['code'] = 502
        return JsonResponse(result)


# 显示主界面
def main(request):
    if request.method == 'GET':
        # auth = Users.objects.values('account', 'belongs', 'auth').get(
        #     account='request.COOKIES.get('who')')
        auth = Users.objects.values('account', 'belongs', 'auth').get(
            account='test1')

        return render(request, 'users/main.html', auth)


# 注册
@require_POST
def sign_up(request):
    ask = json.loads(str(request.body, encoding='UTF-8'))
    rst = net_tools.get_json_temp()
    query = Users.objects.filter(
        Q(account=ask['account']) | Q(belongs=ask['belongs']))
    if query.exists():
        rst.meta['code'] = 500
        rst.meta['msg'] = '账号或归属人已存在'
    else:
        try:
            target = Users()
            target.account = ask['account']
            target.belongs = ask['belongs']
            target.password = make_password(ask['password'])
            target.add_date = time.strftime(
                "%Y-%m-%d %H:%M:%S", time.localtime())
            target.save()
        except Exception as e:
            print(e)
            rst.meta['code'] = 501
            rst.meta['msg'] = '注册时异常，请联系管理员'
    return JsonResponse(rst.__str__())


def disable_users(request):
    if request.method == 'POST':
        who = request.COOKIES.get('who', '')
        ask = json.loads(str(request.body, encoding='UTF-8'))
        rst = {
            'code': 200,
            'msg': 'ok'
        }
        try:
            targets = Users.objects.filter(account__in=ask['delete_target'])
            for item in targets:
                if item.account == who:
                    rst['msg'] = '删除队列中含有自身账号，已过滤，失效完成！'
                    continue
                else:
                    item.status = 1
                    item.save()
        except Exception as e:
            print(e)
            repr(e)
            rst['code'] = 500
            rst['msg'] = '更新异常'
        return JsonResponse(rst)


def update_users(request):
    if request.method == 'POST':
        ask = json.loads(str(request.body, encoding='UTF-8'))
        rst = {
            'code': 200,
            'msg': 'ok'
        }
        try:
            target = Users.objects.get(account=ask['account'])
            target.belongs = ask['belongs']
            target.password = make_password(ask['password'])
            target.save()
        except Exception as e:
            print(e)
            rst['code'] = 500
            rst['msg'] = '存储错误，请检查'
        return JsonResponse(rst)


def show_users(request):
    """
    展示用户接口
    """
    page_num = request.GET.get('page_num', 1)
    page_count = request.GET.get('page_count', 10)
    rsp = net_tools.get_json_temp()
    from business.helper import page_n
    users = Users.objects.all().values('id', 'account', 'belongs', 'add_date',
                                       'status', 'auth', 'last_time', 'last_ip').order_by('-auth')
    page_n = page_n(users, page_num, page_count)
    rsp.data['users'] = list(page_n.object_list)
    rsp.data['pageInfo'] = {
        'allCount': page_n.paginator.count,
        'pageSize': int(page_count),
        'currentPage': int(page_num)
    }
    return JsonResponse(rsp.__str__())


@require_POST
def update_status(request):
    """
    更新用户状态的接口
    """
    rsp = net_tools.get_json_temp()
    ask = json.loads(str(request.body, encoding='UTF-8'))
    try:
        target = Users.objects.get(id=ask['user_id'])
    except Exception as e:
        rsp.meta['code'] = 500
        rsp.meta['msg'] = '无该用户，请检查...'
    else:
        target.status = 0 if ask['status'] else 1
        target.save()
        return JsonResponse(rsp.__str__())


@require_POST
def add_right(request):
    ask = parse_request(request.body)
    rsp = net_tools.get_json_temp()
    f_id = ask['father'] if ask['father'] else None

    if ask['name'] and ask['desc']:
        level = None
        if f_id:
            level = Auth.objects.get(id=f_id).level + 1
        else:
            level = 1
        if level > net_tools.MIN_AUTH_LEVEL:
            rsp.meta['code'] = 500
            rsp.meta['msg'] = '该权限下不能添加子权限'
            return JsonResponse(rsp.__str__())
        target = Auth()
        target.name = ask['name']
        target.desc = ask['desc']
        target.level = level
        target.father_id = f_id
        target.save()
        rsp.meta['code'] = 200
        rsp.meta['msg'] = '添加权限成功！'
    else:
        rsp.meta['code'] = 501
        rsp.meta['msg'] = '请填写权限名称和权限描述'

    return JsonResponse(rsp.__str__())


@require_GET
def get_right_by_level(request):
    rsp = net_tools.get_json_temp()
    target_level = request.GET.get('level', '')
    if target_level:
        rsp.data['rights'] = list(Auth.objects.values('name', 'id').filter(level=target_level))
    else:
        rsp.meta['code'] = 500
        rsp.meta['msg'] = "请输入正确参数"
    return JsonResponse(rsp.__str__())


@require_POST
def get_all_rights(request):
    rsp = net_tools.get_json_temp()
    all_rights = Auth.objects.values('id', 'name', 'desc', 'level', 'father__name').order_by('level').all()
    rsp.data['rights'] = list(all_rights)
    return JsonResponse(rsp.__str__())


# def get_all_roles(request):
#     rsp = net_tools.get_json_temp()
#     ask = net_tools.parse_request(request.body)
#     roles = Role.objects.values('id', 'name', 'desc', 'father__name', 'gen_time').all()
#     rsp.data['roles'] = list(roles)
#     return JsonResponse(rsp.__str__())


@require_POST
def add_role(request):
    rsp = net_tools.get_json_temp()
    ask = net_tools.parse_request(request.body)
    target = Role()
    target.name = ask['name']
    target.desc = ask['desc']
    target.level = ask['level']
    target.father_id = ask['father'] if ask['father'] else None
    target.save()
    rsp.data['roles'] = list(Role.objects.values('id', 'name', 'desc', 'gen_time', 'father__name', 'level').all())
    return JsonResponse(rsp.__str__())


@require_POST
def rm_role(request):
    rsp = net_tools.get_json_temp()
    ask = net_tools.parse_request(request.body)
    try:
        target = Role.objects.get(id=ask['id'])
        Role.objects.filter(father_id=ask['id']).update(father=None)
        target.delete()
        rsp.data['roles'] = list(Role.objects.values('id', 'name', 'desc', 'level', 'gen_time', 'father__name').all())
    except Role.DoesNotExist:
        rsp.meta['code'] = 500
        rsp.meta['msg'] = '目标不存在'
    return JsonResponse(rsp.__str__())


@require_POST
def update_role(request):
    rsp = net_tools.get_json_temp()
    ask = net_tools.parse_request(request.body)
    try:
        new_father = Role.objects.get(id=ask['father_id']) if ask['father_id'] else None
        target = Role.objects.get(id=ask['id'])
        target.name = ask['name']
        target.desc = ask['desc']
        target.level = ask['level']
        target.father = new_father
        target.save()
        rsp.data['roles'] = list(Role.objects.values('id', 'name', 'desc', 'gen_time', 'father__name', 'level').all())
    except Role.DoesNotExist:
        rsp.meta['code'] = 500
        rsp.meta['msg'] = '要修改的角色或新制定的父类角色不存在'
    return JsonResponse(rsp.__str__())


@require_GET
def get_all_roles(request):
    rsp = net_tools.get_json_temp()
    all_roles = Role.objects.values('id', 'name', 'desc', 'gen_time', 'father_id', 'father__name', 'level').all()
    for i in all_roles:
        item_role_auth = RoleAuth.objects.values_list('auth', flat=True).filter(role_id=i['id'])
        if item_role_auth.exists():
            item_all_auth = Auth.objects.filter(id__in=item_role_auth).values('id', 'name', 'level', 'father_id').all()
            item_tree_auth = net_tools.get_full_tree(item_all_auth)
            i['auth'] = net_tools.get_tree_list(item_tree_auth)
        else:
            continue
    rsp.data['roles'] = list(all_roles)
    return JsonResponse(rsp.__str__())


@require_GET
def get_roles_by_level(request):
    rsp = net_tools.get_json_temp()
    level = request.GET.get('level', '')
    except_id = request.GET.get('except', '')
    if level:
        if except_id:
            rsp.data['roles'] = list(Role.objects.values('id', 'name').filter(Q(level=level) & ~Q(id=except_id)))
        else:
            rsp.data['roles'] = list(Role.objects.values('id', 'name').filter(level=level))
    return JsonResponse(rsp.__str__())


@require_GET
def get_all_tree_auth(request):
    """
    获取以树形结构组织的权限结构
    :param request:
    :return:
    """
    rsp = net_tools.get_json_temp()
    auth_node = Auth.objects.values('id', 'name', 'level', 'father_id').order_by('level').all()
    tree_list = net_tools.get_tree_list(auth_node)
    rsp.data['tree_roles'] = tree_list
    return JsonResponse(rsp.__str__())


@require_GET
def get_user_tree_auth(request):
    # 获取用户的权限数据（级别最小的权限）
    user_auth = Auth.objects.values('id', 'name', 'level', 'father_id').filter(level=3).order_by('-level')
    # 通过已经获取的子节点数据，获取完整的list结构
    list_auth = net_tools.get_full_tree(user_auth)
    # 将已经获取好的权限数据进行排序，根据level字段的大小，从小到大进行处理
    list_auth.sort(key=lambda x: x['level'])
    # 将排序好的数组转化为tree
    tree_list = net_tools.get_tree_list(list_auth)
    return HttpResponse(json.dumps(tree_list))


@require_POST
def add_role_auth(request):
    rsp = net_tools.get_json_temp()
    ask = net_tools.parse_request(request.body)

    RoleAuth.objects.filter(role_id=ask['role_id']).delete()

    for i in ask['role_auth']:
        item = RoleAuth()
        item.role_id = ask['role_id']
        item.auth_id = i
        item.save()

    item_role_auth = RoleAuth.objects.values_list('auth', flat=True).filter(role_id=ask['role_id'])
    item_all_auth = Auth.objects.filter(id__in=item_role_auth).values('id', 'name', 'level', 'father_id').all()
    item_tree_auth = net_tools.get_full_tree(item_all_auth)
    rsp.data['new_auth'] = net_tools.get_tree_list(item_tree_auth)
    return JsonResponse(rsp.__str__())


@require_POST
def rm_role_auth(request):
    rsp = net_tools.get_json_temp()
    ask = net_tools.parse_request(request.body)
    targetUser = ask['userId']
    targetAuth = ask['rmAuth']
    RoleAuth.objects.get(role_id=targetUser, auth_id=targetAuth).delete()

    item_role_auth = RoleAuth.objects.values_list('auth', flat=True).filter(role_id=targetUser)
    item_all_auth = Auth.objects.filter(id__in=item_role_auth).values('id', 'name', 'level', 'father_id').all()
    item_tree_auth = net_tools.get_full_tree(item_all_auth)
    rsp.data['new_auth'] = net_tools.get_tree_list(item_tree_auth)
    return JsonResponse(rsp.__str__())


@require_GET
def test(request):
    urls = net_tools.get_all_url_dict()
    print(urls)
    return HttpResponse(urls)
